Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add node:timers module #3346

Merged
merged 1 commit into from
Jan 18, 2025
Merged

add node:timers module #3346

merged 1 commit into from
Jan 18, 2025

Conversation

anonrig
Copy link
Member

@anonrig anonrig commented Jan 16, 2025

Once this lands, we can directly connect to mysql using "mysql" npm package from workers.

@anonrig anonrig requested a review from jasnell January 16, 2025 16:25
@anonrig anonrig requested review from a team as code owners January 16, 2025 16:25
@anonrig anonrig force-pushed the yagiz/add-node-timers-implementation branch 3 times, most recently from aef241c to 04fb5ad Compare January 16, 2025 16:45
Copy link
Contributor

@vicb vicb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added inline comments.

Would be nice to add test for active and unenroll which are added by this PR

src/node/internal/internal_timers.ts Outdated Show resolved Hide resolved
src/node/internal/internal_timers.ts Outdated Show resolved Hide resolved
src/node/internal/internal_timers.ts Show resolved Hide resolved
src/node/internal/internal_timers.ts Show resolved Hide resolved
src/node/internal/internal_timers.ts Outdated Show resolved Hide resolved
src/workerd/api/node/tests/timers-nodejs-test.js Outdated Show resolved Hide resolved
@anonrig anonrig force-pushed the yagiz/add-node-timers-implementation branch 2 times, most recently from 23b0804 to 4085a6d Compare January 16, 2025 20:47
@anonrig anonrig requested review from jasnell and vicb January 16, 2025 20:50
@anonrig anonrig force-pushed the yagiz/add-node-timers-implementation branch from 4085a6d to 9d22c45 Compare January 16, 2025 21:05
Copy link
Contributor

@vicb vicb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we consider changing the global functions in node compat mode?

It weird that globalThis.setTimeout !== nodeTimer.setTimeout and they return a different type. IIUC globalThis.clearTimeour(nodeTimer.setTimeout(...)) will not work.

Edit: found my original comment

@anonrig anonrig force-pushed the yagiz/add-node-timers-implementation branch from 9d22c45 to aa66c19 Compare January 17, 2025 00:56
@jasnell
Copy link
Member

jasnell commented Jan 17, 2025

Should we consider changing the global functions in node compat mode?

No, that would end up being a breaking change. I can foresee possibly adding a separate compat flag to do so but the ship has already sailed...

That said, we could probably make it so that globalThis.clearTimeout(nodeTimer.setTimeout()) (and vis versa) would work without too much difficulty

@vicb
Copy link
Contributor

vicb commented Jan 17, 2025

Should we consider changing the global functions in node compat mode?

No, that would end up being a breaking change. I can foresee possibly adding a separate compat flag to do so but the ship has already sailed...

That said, we could probably make it so that globalThis.clearTimeout(nodeTimer.setTimeout()) (and vis versa) would work without too much difficulty

In node we can do:

const timeout = setTimeout(...);
timeout.refresh(); // crashes, timeout is a number

We can not do it in worked (both before or after this PR).

One thing that we can do in workerd after this PR is:

import nodeTimers from `node:timers`;
const timeout = nodeTimers.setTimeout(...);
timeout.refresh();

Meaning globalThis.setTimeout is not the same as nodeTimers.setTimeout which I don't think is the right thing to do.

I can foresee possibly adding a separate compat flag to do so but the ship has already sailed...

I don't agree here. I consider this a bug fix that we have to do. That is I think globalThis.setTimeout must return an instance of Timeout as Node does and not a number as it does currently - and I agree there should be a flag.

I think there is no rush to merge this PR at least before we discuss an agree on what the behavior should be.

I think the behavior introduced in this PR can be implemented in unenv for now. In fact [email protected] already has the changes enabling mysql, there is a pending PR to integrate it into wrangler - so ETA is next Tuesday.

edit:

And I think we could safely say that it is a bug fix instead of breaking change.

Because the only thing this can break is typing, i.e. workerd currently returns a number but users never do any operation on that number. They might only pass that number to clearTimeout or clearInterval. So what they might need to do is to update a type from number to Timeout.

vicb
vicb previously requested changes Jan 17, 2025
Copy link
Contributor

@vicb vicb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need more discussion before landing this.

@anonrig
Copy link
Member Author

anonrig commented Jan 17, 2025

I think we need more discussion before landing this.

@vicb Whether or not changing global setTimeout/setImmediate is not within the scope of this pull-request. We already have most of the node:timers through the polyfill, hence, this pull-request is not changing anything that isn't out there. Since this enables mysql and there are teams/customers waiting for this pull-request to land, I propose postponing the discussion of globals once this PR lands, and proceed with this PR.

@jasnell
Copy link
Member

jasnell commented Jan 17, 2025

Meaning globalThis.setTimeout is not the same as nodeTimers.setTimeout which I don't think is the right thing to do.

These are different APIs. Workers is Web compatible first and we're not going to change the behavior of globalThis.setTimeout(...) to match Node.js. Perhaps we can do so at some point with an explicitly opt-in compatibility flag but by default our globalThis.setTimeout(...) should follow the web platform spec while require('node:timer').setTimeout(...) will follow Node.js' spec. The fact that these have different returns and different behaviors is just something we'll have to accept.

I don't agree here. I consider this a bug fix that we have to do. That is I think globalThis.setTimeout must return an instance of Timeout as Node does and not a number as it does currently - and I agree there should be a flag.

Strong -1 on this. It's not a bug that globalThis.setTimeout(...) conforms to the web platform API specification for setTimeout and it's not a bug that nodeTimer.setTimeout(...) conforms to the Node.js version of setTimeout(...). The fact that these work differently is just something we'll need to put up with.

We would be absolutely no different than Deno with this. In Deno, like the implementation here, has globalThis.setTimeout(...) conforming the web platform spec and the node:timers version conforming to Node.js.

image

@vicb
Copy link
Contributor

vicb commented Jan 17, 2025

@anonrig you said:

Since this enables mysql and there are teams/customers waiting for this pull-request to land, I propose postponing the discussion of globals once this PR lands, and proceed with this PR.

What I said is:

I think the behavior introduced in this PR can be implemented in unenv for now. In fact [email protected] already has the changes enabling mysql, there is a cloudflare/workers-sdk#7806 to integrate it into wrangler - so ETA is next Tuesday.

So my understanding is that "teams/customers waiting for this pull-request to land" will be satisfied with the unenv update alone, but please correct me if I am wrong.

@jasnell
Copy link
Member

jasnell commented Jan 17, 2025

@vicb ... I acknowledge that the situation is unfortunate. Node.js should never have implemented this API in a non-web compatible way, but it did. This is not a reason to block and this is blocking progress on other things. I'm going to dismiss your block so this can proceed.

@jasnell jasnell dismissed vicb’s stale review January 17, 2025 20:55

See comments

@anonrig anonrig force-pushed the yagiz/add-node-timers-implementation branch from aa66c19 to 1a1c7e6 Compare January 17, 2025 21:15
@anonrig anonrig force-pushed the yagiz/add-node-timers-implementation branch from 1a1c7e6 to 2bef052 Compare January 17, 2025 21:16
@anonrig anonrig merged commit 70e389b into main Jan 18, 2025
15 checks passed
@anonrig anonrig deleted the yagiz/add-node-timers-implementation branch January 18, 2025 00:29
@irvinebroque
Copy link
Collaborator

Nice one. Ship it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants